package com.recipedb.recipedb.repository;

import com.recipedb.recipedb.entity.Recipe;
import jakarta.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import org.springframework.data.repository.query.Param;
import java.util.List;
import org.springframework.data.jpa.repository.Modifying;

@Repository
public interface RecipeRepository extends JpaRepository<Recipe, Long> {

    List<Recipe> findByUserId(Long userId);
    List<Recipe> findByUserIdOrderByCreatedAtDesc(Long userId);

    @Query("SELECT r FROM Recipe r WHERE LOWER(r.title) LIKE LOWER(CONCAT('%', :keyword, '%'))")
    List<Recipe> searchByTitle(@Param("keyword") String keyword);

    @Query("""
        SELECT r FROM Recipe r
        JOIN RecipeCategory rc ON rc.recipeId = r.id
        JOIN Category c ON c.id = rc.categoryId
        WHERE LOWER(c.name) = LOWER(:category)
    """)
    List<Recipe> searchByCategory(@Param("category") String category);

    @Query("""
        SELECT r FROM Recipe r
        JOIN RecipeTag rt ON rt.recipeId = r.id
        JOIN Tag t ON t.id = rt.tagId
        WHERE LOWER(t.name) = LOWER(:tag)
    """)
    List<Recipe> searchByTag(@Param("tag") String tag);

    @Query("""
        SELECT r FROM Recipe r
        JOIN RecipeIngredient ri ON ri.recipeId = r.id
        JOIN Ingredient i ON i.id = ri.ingredientId
        WHERE LOWER(i.name) = LOWER(:ingredient)
    """)
    List<Recipe> searchByIngredient(@Param("ingredient") String ingredient);

    @Modifying
    @Transactional
    @Query("UPDATE Recipe r SET r.title = :title, r.updatedAt = CURRENT_TIMESTAMP WHERE r.id = :id")
    void updateTitle(@Param("id") Long id, @Param("title") String title);

    @Modifying
    @Transactional
    @Query("UPDATE Recipe r SET r.duration = :duration, r.updatedAt = CURRENT_TIMESTAMP WHERE r.id = :id")
    void updateDuration(@Param("id") Long id, @Param("duration") Integer duration);

    @Modifying
    @Transactional
    @Query("UPDATE Recipe r SET r.description = :description, r.updatedAt = CURRENT_TIMESTAMP WHERE r.id = :id")
    void updateDescription(@Param("id") Long id, @Param("description") String description);

    @Modifying
    @Transactional
    @Query("UPDATE Recipe r SET r.coverImage = :coverImage, r.updatedAt = CURRENT_TIMESTAMP WHERE r.id = :id")
    void updateCoverImage(@Param("id") Long id, @Param("coverImage") String coverImage);

    @Modifying
    @Transactional
    @Query("UPDATE Recipe r SET r.difficulty = :difficulty, r.updatedAt = CURRENT_TIMESTAMP WHERE r.id = :id")
    void updateDifficulty(@Param("id") Long id, @Param("difficulty") Integer difficulty);

    @Modifying
    @Transactional
    @Query("UPDATE Recipe r SET r.servings = :servings, r.updatedAt = CURRENT_TIMESTAMP WHERE r.id = :id")
    void updateServings(@Param("id") Long id, @Param("servings") Integer servings);

    List<Recipe> findByUserIdInOrderByCreatedAtDesc(List<Long> userIds);

    @Query("SELECT r.id FROM Recipe r WHERE r.userId = :userId")
    List<Long> findRecipeIdsByUserId(@Param("userId") Long userId);
}